import Utils from './Utils';

export class PlugableContext {
    constructor(owner) {
        this.owner = owner;
        this.data = {};
    }
    execute(pluginsList, reduce) {
        let data = {};
        for (let e of pluginsList) {
            let plugin = this.data[e];
            if (plugin) {
                data = Utils.unpack(reduce(data, plugin));
            } else {
                Utils.error(`cannot found plugin '${e}' of '${this.owner.name}'`);
            }
        }
        return data;
    }
}

function Plugable(target) {
    let cx = target[Plugable.context] = target[Plugable.context] || new PlugableContext();
    target.registerPlugin = function(plugin) {
        cx.data[plugin.name] = plugin;
        if (plugin.alias != null) {
            if (plugin.alias instanceof Array) {
                for (let a of plugin.alias) {
                    cx.data[a] = plugin;
                }
            }
        } else if (typeof plugin.alias === 'string') {
            cx.data[plugin.alias] = plugin;
        }
    };
    target.getPlugin = function(name) {
        return cx.data[name];
    };
}

Plugable.context = Symbol();

export default Plugable;
